﻿using System;
using System.Diagnostics;
using System.Windows.Input;

namespace Wp7Tools.Commands {
	[DebuggerStepThrough]
	public class RelayCommand : ICommand {

        private Action<object> _execute;
		private Predicate<object> _canExecute;
		

        public RelayCommand(Action<object> execute) {
        	_execute = execute;
        }

		public RelayCommand(Action<object> execute, Func<bool> canExecute) : this(execute, obj => canExecute()) {}

		public RelayCommand(Action<object> execute, Predicate<object> canExecute) {
			_execute = execute;
			_canExecute = canExecute;
        }

#if !SILVERLIGHT
		private int _canExecuteRefreshTime;

		DispatcherTimer _dispatcher = new DispatcherTimer();  

        public int CanExecuteRefreshTime {
            get {
                return _canExecuteRefreshTime;
            }
            set {
                if (value == 0) {
                    _dispatcher.IsEnabled = false;
                }
                else if (_canExecuteRefreshTime != value) {
                    _dispatcher.Interval = TimeSpan.FromMilliseconds(value);
                    _dispatcher.IsEnabled = true;
                    _dispatcher.Tick+= (obj, args) => CommandManager.InvalidateRequerySuggested();
                }
                _canExecuteRefreshTime = value;
            }
        }

		public event EventHandler CanExecuteChanged {
			add { CommandManager.RequerySuggested += value; }
			remove { CommandManager.RequerySuggested -= value; }
		}

#else
		public event EventHandler CanExecuteChanged;

		public void RaiseCanExecuteChanged() {
			EventHandler handler = CanExecuteChanged;
			if (handler != null) {
				handler(this, EventArgs.Empty);
			}
		}

#endif
        public bool CanExecute(object parameter) {
            return _canExecute == null ? true : _canExecute(parameter);
        }

        public void Execute(object parameter) {
            _execute(parameter);
        }
    }
}